/*
 * Copyright 2019 Flipkart Internet Pvt. Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.flipkart.ohos.proteus.processor;

import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.global.resource.solidxml.Theme;

import com.flipkart.ohos.proteus.ProteusContext;
import com.flipkart.ohos.proteus.ProteusLayoutInflater;
import com.flipkart.ohos.proteus.ProteusView;
import com.flipkart.ohos.proteus.value.AttributeResource;
import com.flipkart.ohos.proteus.value.ElementValue;
import com.flipkart.ohos.proteus.value.Resource;
import com.flipkart.ohos.proteus.value.StyleResource;
import com.flipkart.ohos.proteus.value.Value;

import java.io.IOException;

/**
 * Use this as the base processor for references like @Element or remote resources with http:// urls.
 */
public abstract class DrawableResourceProcessor<V extends Component> extends AttributeProcessor<V> {
    public static Element evaluate(Value value, ProteusView view) {
        if (value == null) {
            return null;
        }
        final Element[] d = new Element[1];
        DrawableResourceProcessor<Component> processor = new DrawableResourceProcessor<Component>() {
            @Override
            public void setElement(Component view, Element element) {
                d[0] = element;
            }
        };
        processor.process(view.getAsView(), value);
        return d[0];
    }

    public static Value staticCompile(Value value, Context context) {
        if (value == null) {
            return ElementValue.ColorValue.BLACK;
        }
        if (value.isElement()) {
            return value;
        } else if (value.isPrimitive()) {
            Value precompiled = AttributeProcessor.staticPreCompile(value.getAsPrimitive(), context, null);
            if (precompiled != null) {
                return precompiled;
            }
            return ElementValue.valueOf(value.getAsString(), context);
        } else if (value.isObject()) {
            return ElementValue.valueOf(value.getAsObject(), context);
        } else {
            return ElementValue.ColorValue.BLACK;
        }
    }

    @Override
    public void handleValue(final V view, Value value) {
        if (value.isElement()) {
            ElementValue d = value.getAsElement();
            if (null != d) {
                ProteusLayoutInflater.ImageLoader loader = ((ProteusView) view).getViewManager()
                    .getContext().getLoader();
                d.apply((ProteusView) view, view.getContext(), loader, element -> {
                    if (null != element) {
                        setElement(view, element);
                    }
                });
            }
        } else {
            process(view, precompile(value, view.getContext(),
                ((ProteusContext) view.getContext()).getFunctionManager()));
        }
    }

    @Override
    public void handleResource(V view, Resource resource) {
        Theme theme = resource.getElement(view.getContext());
        if (null != theme) {
            ohos.global.resource.Resource resource1 = null;
            try {
                resource1 = theme.getMediaValue(view.getName(), view.getResourceManager());
            } catch (IOException | NotExistException | WrongTypeException e) {
                e.printStackTrace();
            }
            PixelMapElement pixelMapElement = new PixelMapElement(resource1);
            setElement(view, pixelMapElement);
        }
    }

    @Override
    public void handleAttributeResource(V view, AttributeResource attribute) {
        //TypedArray a = attribute.apply(view.getContext());
        //set(view, a);
    }

    @Override
    public void handleStyleResource(V view, StyleResource style) {
        //TypedArray a = style.apply(view.getContext());
        //set(view, a);
    }

    private void set(V view, Element element) {
        if (null != element) {
            setElement(view, element);
        }
    }

    public abstract void setElement(V view, Element element);

    @Override
    public Value compile(Value value, Context context) {
        return staticCompile(value, context);
    }
}
